<script setup>
import { ref, computed, onMounted, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { Loading, DataAnalysis, Document } from '@element-plus/icons-vue'
import {
	getTrueTrainImg,
	getTrueTestImg,
	plotTrainResponseImg,
	plotTestResponseImg,
	plotResidualsTrainImg,
	plotResidualsTestImg,
	bayesSearchCvMseImg,
} from '@/api/product/machineLearning'

const props = defineProps({
	modelValue: {
		type: Object,
		default: () => ({}),
	},
	type: {
		type: String,
		default: '',
	},
})

const emit = defineEmits(['update:modelValue'])

const loading = ref(false)
const error = ref(null)

const apiMap = {
	响应: {
		true: plotTrainResponseImg,
		test: plotTestResponseImg,
	},
	'实际值 - 预测值(验证)': {
		true: '',
		test: '',
	},
	'残差(验证)': {
		true: plotResidualsTrainImg,
		test: plotResidualsTestImg,
	},
	'散点(验证)': {
		true: getTrueTrainImg,
		test: getTrueTestImg,
	},
	'最小 MSE': {
		true: bayesSearchCvMseImg,
		test: '',
	},
}

const getCommonParams = () => ({
	best_params: props.type.includes('最小 MSE')
		? undefined
		: props.modelValue.bestParams || {},
	algorithm: props.modelValue.algorithm,
	file_name: props.modelValue.fileName,
	y: props.modelValue.targetFeatureTable
		?.filter((item) => item.isTarget === true)
		.map((item) => item.name),
	x: props.modelValue.targetFeatureTable
		?.filter((item) => item.isFeature === true)
		.map((item) => item.name),
})

const reEvaluate = async () => {
	if (!apiMap[props.type]?.true) {
		ElMessage.warning(`当前类型 ${props.type} 不支持请求`)
		return
	}

	loading.value = true
	error.value = null

	try {
		const params = getCommonParams()
		let trueRes, testRes

		// 调用真实接口
		trueRes = await apiMap[props.type].true(params).catch((err) => {
			console.error('真实数据请求失败:', err)
			return { data: null }
		})

		// 仅当test接口存在时调用
		if (apiMap[props.type].test) {
			testRes = await apiMap[props.type].test(params).catch((err) => {
				console.error('测试数据请求失败:', err)
				return { data: null }
			})
		} else {
			testRes = { data: null } // 显式设置为空
		}

		// 统一结果格式
		const result = {
			trueImageData: trueRes?.data?.data
				? `data:image/png;base64,${trueRes.data.data}`
				: '',
			testImageData: testRes?.data?.data
				? `data:image/png;base64,${testRes.data.data}`
				: '',
		}

		emit('update:modelValue', { ...props.modelValue, [props.type]: result })
	} catch (err) {
		error.value = err
		ElMessage.error(`请求失败: ${err.message}`)
	} finally {
		loading.value = false
	}
}

defineExpose({
	reEvaluate,
})
</script>

<template>
	<div class="model-evaluation-container">
		<!-- 标题和重新请求按钮 -->
		<div class="evaluation-header">
			<h3>
				{{ props.type
				}}{{ `${props.type.includes('最小 MSE')}` ? '结果' : '结果对比' }}
			</h3>
			<el-button
				type="primary"
				:icon="Loading"
				:loading="loading"
				@click="reEvaluate"
			>
				重新请求
			</el-button>
		</div>

		<!-- 错误提示 -->
		<el-alert
			v-if="error"
			:title="`请求失败: ${error.message}`"
			type="error"
			show-icon
			closable
			class="error-alert"
		/>

		<!-- 图片展示区域 -->
		<div
			class="image-container"
			v-loading="loading"
			element-loading-text="正在生成特征工程图表..."
		>
			<!-- 真实数据图像 -->
			<div class="image-wrapper">
				<div class="image-title">真实数据</div>
				<div class="image-content">
					<img
						v-if="props.modelValue[props.type]?.trueImageData"
						:src="props.modelValue[props.type].trueImageData"
						alt="真实数据图像"
						class="evaluation-image"
					/>
					<el-empty v-else description="暂无真实数据" :image-size="100" />
				</div>
			</div>

			<!-- 测试数据图像 -->
			<div
				class="image-wrapper"
				v-if="props.modelValue[props.type]?.testImageData"
			>
				<div class="image-title">测试数据</div>
				<div class="image-content">
					<img
						v-if="props.modelValue[props.type]?.testImageData"
						:src="props.modelValue[props.type].testImageData"
						alt="测试数据图像"
						class="evaluation-image"
					/>
					<el-empty v-else description="暂无测试数据" :image-size="100" />
				</div>
			</div>
		</div>
	</div>
</template>

<style scoped lang="scss">
.model-evaluation-container {
	padding: 20px;
	background-color: #fff;
	border-radius: 4px;
	box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);

	.evaluation-header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		margin-bottom: 20px;

		h3 {
			margin: 0;
			color: #333;
			font-size: 18px;
		}
	}

	.error-alert {
		margin-bottom: 20px;
	}

	.image-container {
		display: flex;
		gap: 20px;
		margin-top: 20px;

		.image-wrapper {
			flex: 1;
			border: 1px solid #ebeef5;
			border-radius: 4px;
			overflow: hidden;
			display: flex;
			flex-direction: column;

			.image-title {
				padding: 10px;
				background-color: #f5f7fa;
				border-bottom: 1px solid #ebeef5;
				font-weight: bold;
				text-align: center;
			}

			.image-content {
				flex: 1;
				display: flex;
				justify-content: center;
				align-items: center;
				min-height: 300px;
				padding: 20px;

				.evaluation-image {
					max-width: 100%;
					max-height: 400px;
					object-fit: contain;
				}
			}
		}
	}
}
</style>
